home *** CD-ROM | disk | FTP | other *** search
/ Kit PC World De Ampliacion De Windows 95 / Kit PC World de ampliacion de Windows 95.iso / internet / sweeper / samples / olecon~1 / framewrk / classf.cpp < prev    next >
Text File  |  1995-11-25  |  11KB  |  397 lines

  1. //=--------------------------------------------------------------------------=
  2. // ClassFactory.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright  1995  Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // contains the implementation of the ClassFactory object. we support 
  13. // IClassFactory and IClassFactory2
  14. //
  15. #include "IPServer.H"
  16. #include "LocalSrv.H"
  17.  
  18. #include "ClassF.H"
  19. #include "Globals.H"
  20. #include "Unknown.H"                    // for CREATEFNOFOBJECT
  21.  
  22. //=--------------------------------------------------------------------------=
  23. // private module level data
  24. //=--------------------------------------------------------------------------=
  25. //
  26.  
  27. // ASSERT and FAIL require this
  28. //
  29. SZTHISFILE
  30.  
  31. // private routines for this file
  32. //
  33. HRESULT   CreateOleObjectFromIndex(IUnknown *, int Index, void **, REFIID);
  34.  
  35. //=--------------------------------------------------------------------------=
  36. // CClassFactory::CClassFactory
  37. //=--------------------------------------------------------------------------=
  38. // create the object and initialize the refcount
  39. //
  40. // Parameters:
  41. //    int            - [in] index into our global table of objects for this guy
  42. //
  43. // Notes:
  44. //
  45. CClassFactory::CClassFactory
  46. (
  47.     int iIndex
  48. )
  49. : m_iIndex(iIndex)
  50. {
  51.     m_cRefs = 1;
  52. }
  53.  
  54.  
  55. //=--------------------------------------------------------------------------=
  56. // CClassFactory::CClassFactory
  57. //=--------------------------------------------------------------------------=
  58. // "Life levels all men.  Death reveals the eminent."
  59. // - George Bernard Shaw (1856 - 1950)
  60. //
  61. // Notes:
  62. //
  63. CClassFactory::~CClassFactory ()
  64. {
  65.     ASSERT(m_cRefs == 0, "Gaaak! I'm being deleted with refs!");
  66.     return;
  67. }
  68.  
  69. //=--------------------------------------------------------------------------=
  70. // CClassFactory::QueryInterface
  71. //=--------------------------------------------------------------------------=
  72. // the user wants another interface.  we won't give 'em. very many.
  73. //
  74. // Parameters:
  75. //    REFIID        - [in]  interface they want
  76. //    void **       - [out] where they want to put the resulting object ptr.
  77. //
  78. // Output:
  79. //    HRESULT       - S_OK, E_NOINTERFACE
  80. //
  81. // Notes:
  82. //
  83. STDMETHODIMP CClassFactory::QueryInterface
  84. (
  85.     REFIID riid,
  86.     void **ppvObjOut
  87. )
  88. {
  89.     void *pv;
  90.  
  91.     CHECK_POINTER(ppvObjOut);
  92.  
  93.     // we support IUnknown, and the two CF interfaces
  94.     //
  95.     if (DO_GUIDS_MATCH(riid, IID_IClassFactory)) {
  96.         pv = (void *)(IClassFactory *)this;
  97.     } else if (DO_GUIDS_MATCH(riid, IID_IClassFactory2)) {
  98.         pv = (void *)(IClassFactory2 *)this;
  99.     } else if (DO_GUIDS_MATCH(riid, IID_IUnknown)) {
  100.         pv = (void *)(IUnknown *)this;
  101.     } else {
  102.         *ppvObjOut = NULL;
  103.         return E_NOINTERFACE;
  104.     }
  105.  
  106.     ((IUnknown *)pv)->AddRef();
  107.     *ppvObjOut = pv;
  108.     return S_OK;
  109. }
  110.  
  111.  
  112.  
  113.  
  114. //=--------------------------------------------------------------------------=
  115. // CClassFactory::AddRef
  116. //=--------------------------------------------------------------------------=
  117. // adds a tick to the current reference count.
  118. //
  119. // Output:
  120. //    ULONG        - the new reference count
  121. //
  122. // Notes:
  123. //
  124. ULONG CClassFactory::AddRef
  125. (
  126.     void
  127. )
  128. {
  129.     return ++m_cRefs;
  130. }
  131.  
  132. //=--------------------------------------------------------------------------=
  133. // CClassFactory::Release
  134. //=--------------------------------------------------------------------------=
  135. // removes a tick from the count, and delets the object if necessary
  136. //
  137. // Output:
  138. //    ULONG         - remaining refs
  139. //
  140. // Notes:
  141. //
  142. ULONG CClassFactory::Release
  143. (
  144.     void
  145. )
  146. {
  147.     ASSERT(m_cRefs, "Maggots! No Refs, and we're being released!");
  148.     if(--m_cRefs)
  149.         return m_cRefs;
  150.  
  151.     delete this;
  152.     return 0;
  153. }
  154.  
  155. //=--------------------------------------------------------------------------=
  156. // CClassFactory::CreateInstance
  157. //=--------------------------------------------------------------------------=
  158. // create an instance of some sort of object.
  159. //
  160. // Parameters:
  161. //    IUnknown *        - [in]  controlling IUknonwn for aggregation
  162. //    REFIID            - [in]  interface id for new object
  163. //    void **           - [out] pointer to new interface object.
  164. //
  165. // Output:
  166. //    HRESULT           - S_OK, E_NOINTERFACE, E_UNEXPECTED,
  167. //                        E_OUTOFMEMORY, E_INVALIDARG
  168. //
  169. // Notes:
  170. //
  171. STDMETHODIMP CClassFactory::CreateInstance
  172. (
  173.     IUnknown *pUnkOuter,
  174.     REFIID    riid,
  175.     void    **ppvObjOut
  176. )
  177. {
  178.     // check args
  179.     //
  180.     if (!ppvObjOut)
  181.         return E_INVALIDARG;
  182.  
  183.     // check to see if we've done our licensing work.  we do this as late
  184.     // as possible that people calling CreateInstanceLic don't suffer from
  185.     // a performance hit here.
  186.     //
  187.     if (!g_fCheckedForLicense) {
  188.         g_fMachineHasLicense = CheckForLicense();
  189.         g_fCheckedForLicense = TRUE;
  190.     }
  191.  
  192.     // check to see if they have the appropriate license to create this stuff
  193.     //
  194.     if (!g_fMachineHasLicense)
  195.         return CLASS_E_NOTLICENSED;
  196.  
  197.     // try to create one of the objects that we support
  198.     //
  199.     return CreateOleObjectFromIndex(pUnkOuter, m_iIndex, ppvObjOut, riid);
  200. }
  201.  
  202. //=--------------------------------------------------------------------------=
  203. // CClassFactory::LockServer
  204. //=--------------------------------------------------------------------------=
  205. // lock the server so we can't unload
  206. //
  207. // Parameters:
  208. //    BOOL        - [in] TRUE means addref, false means release lock count.
  209. //
  210. // Output:
  211. //    HRESULT     - S_OK, E_FAIL, E_OUTOFMEMORY, E_UNEXPECTED
  212. //
  213. // Notes:
  214. //
  215. STDMETHODIMP CClassFactory::LockServer
  216. (
  217.     BOOL fLock
  218. )
  219. {
  220.     // update the lock count.
  221.     //
  222.     if (fLock) 
  223.         g_cLocks++;
  224.     else {
  225.         ASSERT(g_cLocks, "D'oh! Lock Counting Problem");
  226.         g_cLocks--;
  227.     }
  228.  
  229.     return S_OK;
  230. }
  231.  
  232. //=--------------------------------------------------------------------------=
  233. // CClassFactory::GetLicInfo
  234. //=--------------------------------------------------------------------------=
  235. // IClassFactory2 GetLicInfo
  236. //
  237. // Parameters:
  238. //    LICINFO *          - unclear
  239. //
  240. // Output:
  241. //    HRESULT            - unclear
  242. //
  243. // Notes:
  244. //
  245. STDMETHODIMP CClassFactory::GetLicInfo
  246. (
  247.     LICINFO *pLicInfo
  248. )
  249. {
  250.     CHECK_POINTER(pLicInfo);
  251.  
  252.     pLicInfo->cbLicInfo = sizeof(LICINFO);
  253.  
  254.     // This says whether RequestLicKey will work
  255.     //
  256.     pLicInfo->fRuntimeKeyAvail = g_fMachineHasLicense;
  257.  
  258.     // This says whether the standard CreateInstance will work
  259.     //
  260.     pLicInfo->fLicVerified = g_fMachineHasLicense;
  261.  
  262.     return S_OK;
  263. }
  264.  
  265.  
  266. //=--------------------------------------------------------------------------=
  267. // CClassFactory::RequestLicKey
  268. //=--------------------------------------------------------------------------=
  269. // IClassFactory2 RequestLicKey
  270. //
  271. // Parameters:
  272. //    DWORD             - [in]  reserved
  273. //    BSTR *            - [out] unclear
  274. //
  275. // Output:
  276. //    HRESULT           - unclear
  277. //
  278. // Notes:
  279. //
  280. STDMETHODIMP CClassFactory::RequestLicKey
  281. (
  282.     DWORD  dwReserved,
  283.     BSTR  *pbstr
  284. )
  285. {
  286.     // if the machine isn't licensed, then we're not about to give this to them !
  287.     //
  288.     if (!g_fMachineHasLicense)
  289.         return CLASS_E_NOTLICENSED;
  290.  
  291.     *pbstr = SysAllocString(g_wszLicenseKey);
  292.     return (*pbstr) ? S_OK : E_OUTOFMEMORY;
  293. }
  294.  
  295.  
  296. //=--------------------------------------------------------------------------=
  297. // CClassFactory::CreateInstanceLic
  298. //=--------------------------------------------------------------------------=
  299. // create a new instance given a licensing key, etc ...
  300. //
  301. // Parameters:
  302. //    IUnknown *        - [in]  controlling IUnknown for aggregation
  303. //    IUnknown *        - [in]  reserved, must be NULL
  304. //    REFIID            - [in]  IID We're looking for.
  305. //    BSTR              - [in]  license key
  306. //    void **           - [out] where to put the new object.
  307. //
  308. // Output:
  309. //    HRESULT           - unclear
  310. //
  311. // Notes:
  312. //
  313. STDMETHODIMP CClassFactory::CreateInstanceLic
  314. (
  315.     IUnknown *pUnkOuter,
  316.     IUnknown *pUnkReserved,
  317.     REFIID    riid,
  318.     BSTR      bstrKey,
  319.     void    **ppvObjOut
  320. )
  321. {
  322.     BOOL  fMatch;
  323.  
  324.     *ppvObjOut = NULL;
  325.  
  326.     // go and see if the key they gave us matches.
  327.     //
  328.     fMatch = ( 0 == lstrcmpW(g_wszLicenseKey, bstrKey));
  329.     if (!fMatch)
  330.         return CLASS_E_NOTLICENSED;
  331.  
  332.     // if it does, then go and create the object.
  333.     //
  334.     return CreateOleObjectFromIndex(pUnkOuter, m_iIndex, ppvObjOut, riid);
  335. }
  336.  
  337. //=--------------------------------------------------------------------------=
  338. // CreateOleObjectFromIndex
  339. //=--------------------------------------------------------------------------=
  340. // given an index in our object table, create an object from it.
  341. //
  342. // Parameters:
  343. //    IUnknown *       - [in]  Controlling Unknown, if any, for aggregation
  344. //    int              - [in]  index into our global table
  345. //    void **          - [out] where to put resulting object.
  346. //    REFIID           - [in]  the interface they want resulting object to be.
  347. //
  348. // Output:
  349. //    HRESULT          - S_OK, E_OUTOFMEMORY, E_NOINTERFACE
  350. //
  351. // Notes:
  352. //
  353. HRESULT CreateOleObjectFromIndex
  354. (
  355.     IUnknown *pUnkOuter,
  356.     int       iIndex,
  357.     void    **ppvObjOut,
  358.     REFIID    riid
  359. )
  360. {
  361.     IUnknown *pUnk = NULL;
  362.     HRESULT   hr;
  363.  
  364.     // go and create the object
  365.     //
  366.     ASSERT(CREATEFNOFOBJECT(iIndex), "Maggots!  All creatable objects must have creation fn!");
  367.     pUnk = CREATEFNOFOBJECT(iIndex)(pUnkOuter);
  368.  
  369.     // sanity check and make sure the object actually got allocated.
  370.     //
  371.     RETURN_ON_NULLALLOC(pUnk);
  372.  
  373.     // make sure we support aggregation here properly -- if they gave us
  374.     // a controlling unknown, then they -must- ask for IUnknown, and we'll
  375.     // give them the private unknown the object gave us.
  376.     //
  377.     if (pUnkOuter) {
  378.         if (!DO_GUIDS_MATCH(riid, IID_IUnknown))
  379.             return E_INVALIDARG;
  380.  
  381.         *ppvObjOut = (void *)pUnk;
  382.         hr = S_OK;
  383.     } else {
  384.  
  385.         // QI for whatever the user wants.
  386.         //
  387.         hr = pUnk->QueryInterface(riid, ppvObjOut);
  388.         pUnk->Release();
  389.         RETURN_ON_FAILURE(hr);
  390.     }
  391.  
  392.     return hr;
  393. }
  394.  
  395.  
  396.  
  397.